package com.iespring.config.shiro;

import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.LinkedHashMap;

/**
 * shiro的组件注册及其组件之间的依赖关系
 *
 * @since 2022/12/28 19:25
 */
@Configuration
public class ShiroConfig {

    /**
     * Admin(后台管理的Filter)
     *  配置Shiro内置过滤器拦截范围
     *  anon:无需认证即可访问
     *  authc:需要认证才可以访问
     *  user:点击记住我即可访问
     *  logout:登出
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean adminShiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        // 后台系统的filter
        filterChainDefinitionMap.put("/admin/auth/login", "anon");
        filterChainDefinitionMap.put("/admin/auth/info", "anon");
        filterChainDefinitionMap.put("/admin/auth/401", "anon");

        // TODO : admin开头的请求,都要经过认证才行(等待开发完成在做拦截，把anon改成authc)
        filterChainDefinitionMap.put("/admin/**", "authc");
        // 对于没有访问权限的重定向地址
        shiroFilterFactoryBean.setLoginUrl("/admin/auth/401");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
    /**
     * 配置Shiro内置过滤器拦截范围
     * anon:无需认证即可访问
     * authc:需要认证才可以访问
     * user:点击记住我即可访问
     * logout:登出
     *
     * @since 2022/12/26 23:23
     */
//    @Bean
//    public DefaultShiroFilterChainDefinition shiroFilterChainDefinition() {
//        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
//        // 后台系统的filter/无需认证即可访问
//        definition.addPathDefinition("/admin/auth/login","anon");
//        definition.addPathDefinition("/admin/auth/info","anon");
//        definition.addPathDefinition("/admin/auth/401","anon");
//        //配置登出过滤器
//        definition.addPathDefinition("/admin/auth/logout", "logout");
//        return definition;
//    }

    /**
     * WX shiroFilter
     *
     * @param securityManager
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean wxShiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 提供Filter链
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        // 小程序的认证请求
        filterChainDefinitionMap.put("/wx/cart/goodscount", "anon");
        filterChainDefinitionMap.put("/wx/user/index", "authc");
        filterChainDefinitionMap.put("/wx/cart/**", "authc");
        filterChainDefinitionMap.put("/wx/collect/**", "authc");
        filterChainDefinitionMap.put("/wx/address/**", "authc");
        filterChainDefinitionMap.put("/wx/order/**", "authc");
        filterChainDefinitionMap.put("/wx/footprint/**", "authc");
        filterChainDefinitionMap.put("/wx/coupon/**", "authc");

        // 对于没有访问权限的重定向地址
        shiroFilterFactoryBean.setLoginUrl("/wx/auth/401");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }

    /**
     * shiro的核心组件
     *
     * @return
     */
    @Bean
    public DefaultWebSecurityManager securityManager(MarketSessionManager sessionManager, MarketRealm marketRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置session会话，用来保证跨域时session的一致性
        securityManager.setSessionManager(sessionManager);
        securityManager.setRealms(Arrays.asList(marketRealm));
        return securityManager;
    }

    /**
     * 注册组件,使得权限与handler方法进行绑定 (与授权有关，也未用到)
     *
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}
